package org.zcl.utils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Package org.zcl.util
 * @PROJECT_NAME: question
 * @DESCRIPTION:
 * @USER: zhuchenglin
 * @DATE: 2021/12/24 14:07
 */
@Slf4j
public class CacheUtil {

    @Resource(name = "redisTemplate")
    private RedisTemplate redisTemplate;

    public String getString(String key) {
        try {
            return (String) this.redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("获取缓存异常", e);
            return null;
        }
    }

    public Integer getInteger(String key) {
        try {
            return (Integer) this.redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("获取缓存异常", e);
            return null;
        }
    }

    public Long getLong(String key) {
        try {
            return (Long) this.redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("获取缓存异常", e);
            return null;
        }
    }

    public Double getDouble(String key) {
        try {
            return (Double) this.redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("获取缓存异常", e);
            return null;
        }
    }

    public <T> T get(String key) {
        return (T) this.redisTemplate.opsForValue().get(key);
    }

    public <T> T get(String key, TypeReference<T> typeReference) {
        Object result = this.redisTemplate.opsForValue().get(key);

        if (result instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) result;
            return (T) jsonObject.toJavaObject(typeReference);
        }
        return (T) result;
    }

    public void set(String key, Object value) {
        if (value == null) {
            return;
        }
        set(key, value, 3600000L, TimeUnit.MILLISECONDS);
    }

    public void set(String key, Object value, long expireTime, TimeUnit timeUnit) {
        this.redisTemplate.opsForValue().set(key, value, expireTime, timeUnit);
    }

    public boolean delete(String key) {
        return delete(key, false);
    }

    public boolean delete(String key, boolean match) {
        if (match) {
            Set keys = this.redisTemplate.keys(key + "*");
            long count = this.redisTemplate.delete(keys).longValue();
            return (count > 0L);
        }
        return this.redisTemplate.delete(key).booleanValue();
    }

    public Set<String> keys(String key) {
        return this.redisTemplate.keys(key + "*");
    }

    /**
     * 获取list缓存的内容
     *
     * @param key 键
     * @return
     * @author bfd.zlf
     * @date 14:53 2022/1/20
     */
    public String lPop(String key) {
        try {
            return (String) redisTemplate.opsForList().leftPop(key);
        } catch (Exception e) {
            log.warn("RedisUtils String lPop(String key) failure." + e.getMessage());
            return null;
        }
    }

    public boolean lPush(String key, String value) {
        try {
            redisTemplate.opsForList().leftPush(key, value);
            return true;
        } catch (Exception e) {
            log.warn("RedisUtils lPush(String key,String value) failure." + e.getMessage());
            return false;
        }
    }

    public boolean deleteKey(String key) {
        try {
            redisTemplate.delete(key);
            return true;
        } catch (Exception e) {
            log.warn("RedisUtils deleteKey(String key) failure." + e.getMessage());
            return false;
        }
    }

    /**
     * 放到列表的尾部
     *
     * @param key    键
     * @param values 值集合
     * @return
     * @author bfd.zlf
     * @date 15:40 2022/1/20
     */
    public boolean rightPushAll(String key, List<String> values) {
        try {
            redisTemplate.opsForList().leftPushAll(key, values);
            return true;
        } catch (Exception e) {
            log.warn("RedisUtils rightPushAll(String key, List<Long> values) failure." + e.getMessage());
            return false;
        }
    }
}
